
package com.example.pos_terminal;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Application;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Presentation;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.hardware.display.DisplayManager;
import android.media.AudioManager;
import android.media.SoundPool;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcB;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;

import com.alibaba.fastjson.JSONObject;
import com.decard.NDKMethod.BasicOper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.loopj.android.http.RequestParams;
import com.tencent.smtt.export.external.interfaces.ConsoleMessage;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import bean.AraStoreLog;
import bean.ItemPriceAccountModel;
import config.ApiClient;
import config.CommonValue;
import db.TaskManager;
import receiver.ScanCodeBroadcastReceiver;
import service.TimerSyncService;
import tools.GetMacAddress;
import tools.M1CardUtil;
import tools.MD5Util;
import tools.SystemUtil;
import tools.TimeTools;

import static tools.Finals.deka_product_model;
import static tools.Finals.shangmi_product_model;
import static tools.GetMacAddress.getMacAddress;

public class MainActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {

    public final static int REQUEST_READ_PHONE_STATE = 1;
    private static final String TAG = "";
    private long exitTime;
    private TaskManager taskManager;
    private X5WebView webView;
    private ExecutorService executorService;
    private pay pay;
    private String result = "";
    private long firstTime = 0;
    private HelpHandPresentation helpHandPresentation;
    private boolean show = false;
    private static Context context;
    private StringBuffer code = new StringBuffer();
    private ScanCodeBroadcastReceiver setOnReceive;
    private IntentFilter[] mIntentFilter;
    private PendingIntent mPendingIntent;
    private PendingIntent pendingIntent;
    private String[][] mTechList;
    private NfcAdapter mNfcAdapter;
    private Handler myHandler = new Handler();
    private static final String ACTION_DATA_CODE_RECEIVED = "com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED";
    private static final String DATA = "data";
    private BroadcastReceiver receiver;
    private IntentFilter filter;
    public static boolean isPaying = false;
    public static boolean timeStop = true;
    public SoundPool soundPool = null;
    // 要申请的权限
    private String[] permissions = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE,
//            Manifest.permission.CAMERA,
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        setContentView(R.layout.activity_main);
        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
        } else {
            //TODO
        }
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String code = intent.getStringExtra(DATA);
                System.out.println("code+++++++" + code);
                if (code != null && !code.isEmpty() && code.length() >= 11 && isPaying) {
                    if (code.contains("&")) {
                        //虚拟卡账户支付
                        System.out.println("虚拟卡账户支");
                        card(code.trim());
                    } else if(CommonValue.openPay){
                        ///////在此写权限 true开启支付 false关闭支付
                        webView.post(() -> webView.loadUrl("javascript:fn('" + code + "')"));
                        webView.post(() -> webView.loadUrl("javascript:flow('" + code + "')"));
                        isPaying = false;
                    }else{
                        webView.post(() -> webView.loadUrl("javascript:flow('" + code + "')"));
                    }
                }
            }
        };
        filter = new IntentFilter();
        filter.addAction(ACTION_DATA_CODE_RECEIVED);
        //向系统申请使用USB权限,此过程为异步,建议放在程序启动时调用。
        BasicOper.dc_AUSB_ReqPermission(this);//打开端口，usb模式，打开之前必须确保已经获取到USB权限，返回值为设备句柄号。
        int devHandle = BasicOper.dc_open("COM", null, "/dev/ttyHSL1", 115200);//返回值为设备句柄号。
        if (devHandle > 0) {
            Log.d("open", "dc_open success devHandle = " + devHandle);
        }
        initViews();
        context = MainActivity.this;
        if (deka_product_model.equals(SystemUtil.getSystemModel())) {
        } else if (shangmi_product_model.equals(SystemUtil.getSystemModel())) {
            init();
            nfcCheck();
        }


    }

    private void init() {
        // NFCActivity 一般设置为: SingleTop模式 ，并且锁死竖屏，以避免屏幕旋转Intent丢失
        Intent intent = new Intent(MainActivity.this, MainActivity.class);

        // 私有的请求码
        final int REQUEST_CODE = 1 << 16;

        final int FLAG = 0;
        mPendingIntent = PendingIntent.getActivity(MainActivity.this, REQUEST_CODE, intent, FLAG);

        // 三种过滤器
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        IntentFilter tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
        IntentFilter tag = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
        mIntentFilter = new IntentFilter[]{ndef, tech, tag};

        // 只针对ACTION_TECH_DISCOVERED
        mTechList = new String[][]{
                {IsoDep.class.getName()}, {NfcA.class.getName()}, {NfcB.class.getName()},
                {NfcV.class.getName()}, {NfcF.class.getName()}, {Ndef.class.getName()}};

    }

    /**
     * 检测是否支持 NFC
     */
    private void nfcCheck() {
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mNfcAdapter == null) {
            String info = "手机不支付NFC功能";
            return;
        }
        if (!mNfcAdapter.isEnabled()) {
            String info = "手机NFC功能没有打开";
            Intent setNfc = new Intent(Settings.ACTION_NFC_SETTINGS);
            startActivity(setNfc);
        }
    }

    /**
     * 开启检测
     */
    @Override
    public void onResume() {
        super.onResume();
        if (mNfcAdapter == null) return;
        mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilter, mTechList);
    }

    /**
     * 关闭检测
     */
    private String bytesToString(byte[] data) {
        StringBuilder sb = new StringBuilder();
        for (byte d : data) {
            sb.append(String.format("%02X", d));
        }
        return sb.toString();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        //获取nfc卡
        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if (tagFromIntent!=null){

            String CardId = toCardID(tagFromIntent.getId());
            System.out.println(CardId);
            webView.post(() -> webView.loadUrl("javascript:fn(" + CardId + ")"));
        }
//        获取nfc卡id


    }

    private String toCardID(byte[] id) {
        String CardId = "";
        String Card = bytesToString(id).substring(0, 8);
        for (int i = Card.length(); i > 1; i -= 2) {
            CardId += Card.substring(i - 2, i);
            ;
        }
        return String.valueOf(Long.parseLong(CardId, 16));
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_READ_PHONE_STATE:
                if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    //TODO
                }
                break;

            default:
                break;
        }
    }

    private void initViews() {
        taskManager = TaskManager.getInstance(getApplicationContext());
        exitTime = System.currentTimeMillis();
        webView = (X5WebView) findViewById(R.id.webview);
        pay pay = new pay(webView, this,getApplicationContext());
        pay.setMacAddress(getMacAddress());
        GenerateOrder generateOrder = new GenerateOrder(taskManager, this);
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
                Log.i("consoleMessage", consoleMessage.message());
                return super.onConsoleMessage(consoleMessage);
            }
        });
        webView.addJavascriptInterface(pay, "$App");
        webView.addJavascriptInterface(generateOrder, "$order");
        webView.addJavascriptInterface(this, "$screen");
//        webView.loadUrl("http://192.168.137.1:8081/#/");
        webView.loadUrl("file:///android_asset/vue/index.html");
        checkLocalPermission();
        soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
        soundPool.load(MainActivity.this, R.raw.payfail, 1);
        soundPool.load(MainActivity.this, R.raw.topay, 2);
        soundPool.load(MainActivity.this, R.raw.paysuccess, 3);
        soundPool.load(MainActivity.this, R.raw.payagain, 4);
        soundPool.load(MainActivity.this, R.raw.hexiao, 5);
    }

    @Override
    protected void onPause() {
//        unregisterReceiver(receiver);
        super.onPause();
        if (mNfcAdapter == null) return;
        mNfcAdapter.disableForegroundDispatch(this);
        Log.i(TAG, "onPause: 111111111");
        if (helpHandPresentation != null) {
            helpHandPresentation.dismiss();
        }
    }
    @JavascriptInterface
    public void setCustomerProductList(String url, boolean isOk) {
        DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
        Display[] displays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
        Log.e(TAG, "setCustomerProductList: length:" + displays.length);
        if (displays.length > 1) {
            Log.e(TAG, "setCustomerProductList: " + "小屏弹窗超出数量，会造成返回的时候程序奔溃");
            return;
        } else {
            Display display = displays[0];
            Log.e(TAG, "setCustomerProductList: " + "双屏实例为空启用初始化！");
            helpHandPresentation = new HelpHandPresentation(this, display, "ye3.html");
            if (!MainActivity.this.isFinishing()) {
                helpHandPresentation.show();
                //  helpHandPresentation.dismiss();
//                this.runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
                if (helpHandPresentation != null && isOk) {
                }


//                                helpHandPresentation.progressChange(url);
//                              helpHandPresentation.show();
//                            onPause();
                //  helpHandPresentation.dismiss();
//                    }
//                });
            }
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy: invoke--------------");
    }


    public void checkLocalPermission() {
        // 版本判断。当手机系统大于 23 时，才有必要去判断权限是否获取
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            String[] newPermissions = new String[permissions.length];
            List<String> permissionLists = new ArrayList<>();
            for (String p : permissions) {
                // 检查该权限是否已经获取
                int i = ContextCompat.checkSelfPermission(this, p);
                // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
                if (i != PackageManager.PERMISSION_GRANTED) {
                    // 如果没有授予该权限，就去提示用户请求
                    permissionLists.add(p);
                }
            }
            if (permissionLists.size() > 0)
                showDialogTipUserRequestPermission(permissionLists.toArray(new String[permissionLists.size()]));
        }
    }

    // 提示用户该请求权限的弹出框
    private void showDialogTipUserRequestPermission(final String[] needPermission) {
        new AlertDialog.Builder(this)
                .setTitle("存储权限不可用")
                .setMessage("请求访问存储权限")
                .setPositiveButton("立即开启", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startRequestPermission(needPermission);
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                }).setCancelable(false).show();
    }

    // 开始提交请求权限
    private void startRequestPermission(String[] needPermission) {
        ActivityCompat.requestPermissions(this, needPermission, 5);
    }

    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return super.registerReceiver(receiver, filter);
    }

    @Override
    public void unregisterReceiver(BroadcastReceiver receiver) {
        super.unregisterReceiver(receiver);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        int action = event.getAction();
        switch (action) {
            case KeyEvent.ACTION_DOWN:
                break;
            case KeyEvent.ACTION_UP:
                onKeyUp(event.getKeyCode(), event);
                break;
        }
        if (event.getKeyCode() == KeyEvent.KEYCODE_CAMERA || event.getKeyCode() == KeyEvent.KEYCODE_ESCAPE || event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_SUBTRACT) {
            return onKeyDown(event.getKeyCode(), event);
        }
        return super.dispatchKeyEvent(event);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_BACK || event.getKeyCode() == KeyEvent.KEYCODE_ESCAPE || event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_SUBTRACT) {
            webView.post(() -> webView.loadUrl("javascript:ClickFn()"));
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                tuichu();
                break;
            case KeyEvent.KEYCODE_ESCAPE:
                tuichu();
                break;
            case KeyEvent.KEYCODE_NUMPAD_SUBTRACT:
                tuichu();
                break;
        }
        return super.onKeyUp(keyCode, event);
    }

    private boolean tuichu() {
        if (show) {
            long secondTime = System.currentTimeMillis();
            if (secondTime - firstTime > 1000) {
                Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
                firstTime = secondTime;
                return true;
            } else {
                System.exit(0);
            }
        }
        return true;
    }

    @JavascriptInterface
    public void setShow(boolean isOk) {
        show = isOk;
    }

    @JavascriptInterface
    public String version() {
        PackageManager manager = context.getPackageManager();
        String code = "";
        try {
            PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
            code = info.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return code;
    }

    @JavascriptInterface
    public void setBaseApi(String isOk) {
        CommonValue.BASE_API = isOk;
    }

    @JavascriptInterface
    public void stopService() {
//        Intent sync = new Intent(this, TimerSyncService.class);
//        this.stopService(sync);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @JavascriptInterface
    public void startService() {
//        Intent sync = new Intent(this, TimerSyncService.class);
//
//        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
//            this.startForegroundService(sync);
//        }else{
//            this.startService(sync);
//        }

    }

    public X5WebView getWebView() {
        return webView;
    }

    public void card(String scan_2D_info) {
        System.out.println("虚拟卡账户支-----------------1");
        String[] split = scan_2D_info.split("&");
        if (split.length < 4) {
            webView.post(() -> webView.loadUrl("javascript:fn('')"));
            isPaying = true;
            return;
        }
        System.out.println("虚拟卡账户支-----------------2");
        final String time = split[1];
        final String substring = split[2];
        final String paySign = split[0];
        final String idNumber = split[3];
        DateFormat dtf = new SimpleDateFormat("yyMMddHHmmss");
        Calendar oldTime = null;
        try {
            oldTime = TimeTools.string2Calendar(time, dtf);
        } catch (ParseException e) {
            e.printStackTrace();
        }
//        oldTime.add(Calendar.MINUTE, 2);
        Calendar instance = Calendar.getInstance();
        if (oldTime.after(instance)) {
            System.out.println("虚拟卡账户支-----------------3");
            //查询顾客账户信息
            System.out.println("查询顾客账户信息");
            //检验签名
            String str = idNumber + substring + time;
            String sign = MD5Util.getMD5String(str).toUpperCase();
            if (sign.equals(paySign)) {
                //签名验证通过
                System.out.println("签名验证通过");
                String finalCard_number = "javascript:fn('&" + idNumber + "')";
                webView.post(() -> webView.loadUrl(finalCard_number));
                isPaying = false;
            } else {
                payfail();
                Toast.makeText(MainActivity.this, "二维码无效", Toast.LENGTH_SHORT).show();
                String finalCard_number = "javascript:fn('')";
                webView.post(() -> webView.loadUrl(finalCard_number));
                isPaying = true;
            }
        } else {
            payfail();
            isPaying = true;
            System.out.println("二维码超时");
            Toast.makeText(MainActivity.this, "二维码超时", Toast.LENGTH_SHORT).show();
        }
    }

    public BroadcastReceiver getReceiver() {
        return receiver;
    }

    public IntentFilter getFilter() {
        return filter;
    }

    @JavascriptInterface
    public static void openPay(boolean openPay) {
        CommonValue.openPay = openPay;
    }
    @JavascriptInterface
    public  void payIsuccess() {
        soundPool.play(1, 1, 1, 10, 0, 1);
    }
    @JavascriptInterface
    public  void topay() {
        soundPool.play(2, 1, 1, 10, 0, 1);
    }
    @JavascriptInterface
    public  void payfail() {
        soundPool.play(3, 1, 1, 10, 0, 1);
    }
    @JavascriptInterface
    public  void payagain() { soundPool.play(4, 1, 1, 10, 0, 1); }
    @JavascriptInterface
    public void hexiao(){
        soundPool.play(5, 1, 1, 10, 0, 1);
    }

}



